package se19team1e.gui.awt;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;

import se19team1e.controller.Application;
import se19team1e.exception.DataAccessException;
import se19team1e.gui.BaseScreen;

/**
 * 
 * An abstract base screen, to be inherited by all application screens.
 * 
 * <p>
 * Common, reusable functionalities and screen layout can be placed in this class.
 * </p> 
 * 
 * <p>
 * Implements the base screen as a AWT GUI Frame.
 * </p>
 * 
 * @author lai shiaw san
 *
 */
@SuppressWarnings("serial")
public abstract class AWTBaseScreen extends JFrame implements BaseScreen {

    /**
     * A reference to the current application instance.
     */
    private final Application application;
    
    /**
     * An awt JMenu item to login.
     */
    private final JMenuItem loginMenuItem;

    /**
     * An awt JMenu item to logout.
     */
    private final JMenuItem logoutMenuItem;

    /**
     * An awt JMenu item to exit the application.
     */
    private final JMenuItem exitMenuItem;

    /**
     * An awt JMenu item to create new job advert.
     */
    private final JMenuItem createJobAdvertMenuItem;

    /**
     * An awt JMenu item to search job adverts.
     */
    private final JMenuItem searchJobAdvertMenuItem;
    
    /**
     * Get the reference to the current application instance.
     * @return Reference to the current application instance.
     */
    protected Application getApplication() {
        return this.application;
    }
    
    /**
     * Constructs a base screen, initializing with the application instance.
     * @param application Reference to the current application instance.
     */
    protected AWTBaseScreen( Application application ) {
        this.application = application;
        // setup default close behavior to be shut down application!
        this.addWindowListener( new WindowAdapter() {
            /* (non-Javadoc)
             * @see java.awt.event.WindowAdapter#windowClosing(java.awt.event.WindowEvent)
             */
            @Override
            public void windowClosing( WindowEvent event ) {
                // shutdown application!
                getApplication().shutdown();
            }
        } );
        
        // create the JMenu bar
        JMenuBar jMenuBar = new JMenuBar();
        
        // create the file JMenu
        JMenu fileMenu = new JMenu( "Application" );
        jMenuBar.add( fileMenu );
        this.loginMenuItem = new JMenuItem( "Login" );
        this.loginMenuItem.addActionListener( new ActionListener() {
            @Override
            public void actionPerformed( ActionEvent event ) {
                selectLogin();
            }
        });
        fileMenu.add( this.loginMenuItem );
        this.logoutMenuItem = new JMenuItem( "Logout" );
        this.logoutMenuItem.addActionListener( new ActionListener() {
            @Override
            public void actionPerformed( ActionEvent event ) {
                logout();
            }
        });
        fileMenu.add( this.logoutMenuItem );
        this.exitMenuItem = new JMenuItem( "Exit" );
        this.exitMenuItem.addActionListener( new ActionListener() {
            @Override
            public void actionPerformed( ActionEvent event ) {
                shutdownApplication();
            }
        });
        fileMenu.add( this.exitMenuItem );
        
        // create the job advert JMenu
        JMenu jobAdvertMenu = new JMenu( "Job Adverts" );
        this.createJobAdvertMenuItem = new JMenuItem( "Create Job Advert" );
        this.createJobAdvertMenuItem.addActionListener( new ActionListener() {
            @Override
            public void actionPerformed( ActionEvent event ) {
                try {
					selectCreateJobAdvert();
				} catch (DataAccessException e) {
					e.printStackTrace();
				}
            }
        });
        
        // create the search job advert createJobAdvertMenuItem
        jobAdvertMenu.add( this.createJobAdvertMenuItem );
        this.searchJobAdvertMenuItem = new JMenuItem( "Search Job Advert" );
        this.searchJobAdvertMenuItem.addActionListener( new ActionListener() {
            @Override
            public void actionPerformed( ActionEvent event ) {
                selectSearchJobAdvert();
            }
        });
        jobAdvertMenu.add( this.searchJobAdvertMenuItem );
        jMenuBar.add( jobAdvertMenu );
        
        this.setJMenuBar( jMenuBar );
        // End of creating the base AWT screen
    }
    
    /**
     * Displays the create job advert screen.
     * @throws DataAccessException 
     */
    public void selectCreateJobAdvert() throws DataAccessException {
        // delegate to application
        this.application.selectCreateJobAdvert();
    }

    /**
     * Displays the search job advert screen.
     */
    public void selectSearchJobAdvert() {
        // delegate to application
        this.application.selectSearchJobAdvert();
    }
    
    /**
     * Displays the login screen.
     */
    public void selectLogin() {
        // delegate to application
        this.application.selectLogin();
    }

    /**
     * Logs out the current user.
     */
    public void logout() {
        // delegate to application
        this.application.logout();
    }

    /**
     * Shuts down the application.
     */
    public void shutdownApplication() {
        application.shutdown();
    }
    

    /**
     * Enable/disable JMenu items of this screen.
     */
    protected void updateAvailableMenuActions() {
        boolean isLoggedIn = this.getApplication().getCurrentAccount() != null;
        boolean isAdvertiser = this.getApplication().getCurrentAdvertiser() != null;
        
        // enable login if there is no current logged in account
        this.loginMenuItem.setEnabled( !isLoggedIn );
        
        // enable logout if there is current logged in account
        this.logoutMenuItem.setEnabled( isLoggedIn );
        
        // exit is always enabled
        this.exitMenuItem.setEnabled( true );
        
        // enable create job advert if current logged in account is an advertiser
        this.createJobAdvertMenuItem.setEnabled( isAdvertiser );
        
        // always enable search job advert
        this.searchJobAdvertMenuItem.setEnabled( true );
    }

}
